package com.esreport.logstash;

import com.esreport.logstash.cutter.Cutter;
import com.esreport.logstash.parser.LogParser;
import com.esreport.logstash.tracker.LogFile;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;
import java.util.Queue;

/**
 * @author xuweiwei
 * @date 2018/12/26
 */
@Slf4j
public class CollectorTask<T> implements Runnable {
    /**
     * 日志文件
     */
    private LogFile logFile;
    /**
     * 日志内容分割器
     */
    private Cutter cutter;
    /**
     * 日志内容解析器
     */
    private LogParser<T> parser;

    private Queue<T> queue;

    public CollectorTask(Cutter cutter, LogParser parser, LogFile logFile, Queue<T> queue) {
        this.cutter = cutter;
        this.parser = parser;
        this.logFile = logFile;
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            logFile.lock();
            log.info("开始读取日志文件:{}", logFile.getFile().getAbsolutePath());
            long lastModified = logFile.getFile().lastModified();
            //处理切割日志文件的问题
            if (logFile.getFilePoint() > logFile.length()) {
                log.info("日志文件被重新创建,文件:{}", logFile.getFile().getAbsolutePath());
                logFile.reopen();
            }
            RandomAccessFile randomAccessFile = logFile.getAccess();
            String str = null;
            while ((str = cutter.next(randomAccessFile)) != null) {
                try {
                    List<T> list = parser.parse(str);
                    if(list!=null) {
                        queue.addAll(list);
                    }
                } catch (Exception e) {
                    log.error("日志解析出错,内容:{}",str,e);

                }
            }
            if (lastModified > logFile.getLastModified()) {
                logFile.setLastModified(lastModified);
            }
        } catch (IOException e) {
            log.error("访问日志文件发生异常,文件路径:{}", logFile.getFile().getAbsolutePath(), e);
        } finally {
            logFile.unLock();
        }
    }
}
